﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections;
using System.Xml.Linq;

namespace Sofire.Data.XSql
{
    internal class XSqlParametersNode : XSqlNodeBase, IXSqlParametersNode
    {
        public const string NodeName = "parameters";

        public override XSqlType Type
        {
            get { return XSqlType.Parameters; }
        }

        public override XObject CreateXObject()
        {
            XElement element = new XElement(NodeName);
            this.CreateXChildren(element);
            return element;
        }

        protected override void Load(XmlNode node) { }

        public override string Compile(XSqlParameterCollection parameters)
        {
            foreach(var item in this.Children)
            {
                string name;
                object value;
                if(item.Type == XSqlType.Expression)
                {
                    var callNode = item as XSqlExpressionNode;
                    name = callNode.Name;
                    value = callNode.CompileObject(parameters);
                }
                else if(item.Type == XSqlType.XSql)
                {
                    var xsqlNode = item as XSqlNode;
                    name = xsqlNode.Name;
                    var r = this.Document.Engine.ExecuteScalar(this.Document.CreateCommand(xsqlNode, parameters));
                    if(r.IsFailed) throw r.Exception;
                    value = r.Value;
                }
                else if(item.Type == XSqlType.Parameter)
                {
                    var parameterNode = item as XSqlParameterNode;
                    parameterNode.InnerCompile(parameters);
                    continue;
                }
                else
                {
                    this.ThrowException(XSqlError.InvalidNodeType, item.Type.ToString());
                    continue;
                }
                XSqlBindItem bindItem = new XSqlBindItem(name);
                parameters.Add(bindItem.Name, value);
                bindItem.ConvertParameter(parameters);

            }
            return null;
        }
    }
}
